<?php
namespace app\houtai\controller\user;
use app\houtai\controller\BaseController;
use Cassandra\Table;
use think\db\Expression;

class GameController extends BaseController {
    private $isTodo = [0=>'未处理',1 => '举报成功', 2=> '举报失败'];

  /**
   *  @brief  : 用户管理-用户输赢记录
   *  @return : page
   *  @details: 
   */
    public function indexAction() {
        $conds = [];
        $order = [];
        $CHANNELS = $this->GetAdminChannel();
        $GAME_KIND = GetGameKind();
        ////////////////////////////////////////////////////////////////////////////
        $KindID = $this->request->param('KindID/d', 0);
        if ($KindID > 0 && array_key_exists($KindID, $GAME_KIND)) {
            $conds['c.KindID'] = $KindID;
        }
        ////////////////////////////////////////////////////////////////////////////
        $search = $this->request->param('search/s', '', 'trim');
        if (!empty($search)) {
            if ($search > 0) {
                $conds['a.UserID|b.GameID'] = $search;
            } else {
                $conds['b.NickName'] = ['LIKE', "%{$search}%"];
            }
        }
        $RoomID = $this->request->param('RoomID/d', 0);
        if ($RoomID > 0) {
            $conds['a.RoomID'] = $RoomID;
        }

        $time1 = $this->request->param('time1/s', '', 'trim');
        $time2 = $this->request->param('time2/s', '', 'trim');

        $aa = YmdHis2Unix($time1);
        $bb = YmdHis2Unix($time2);
        $ta = date('Y-m-d 00:00:00', $aa);
        $tb = date('Y-m-d 23:59:59', $bb);
        if ($aa > 0) {
            if ($bb > 0) {
                if ($aa <= $bb) {
                    $conds['a.CreateTime'] = ['BETWEEN TIME', [$ta, $tb]];
                } else {
                    $conds['a.CreateTime'] = ['>= TIME', $ta];
                }
            } else {
                $conds['a.CreateTime'] = ['>= TIME', $ta];
            }
        } else {
            if ($bb > 0) {
                $conds['a.CreateTime'] = ['<= TIME', $tb];
            }
        }
        //////////////////////////////////////////////////////
        $Channel = $this->request->param('Channel/d', -1);
        if ($Channel > 0 && array_key_exists($Channel, $CHANNELS)) {
            $conds['b.Channel'][] = ['IN', array_keys($CHANNELS)];
            $conds['b.Channel'][] = ['EQ', $Channel];
        } else {
            $conds['b.Channel'] = ['IN', array_keys($CHANNELS)];
        }
        ////////////////////////////////////////////////////////////////////////////
        $orderMap = [
            'A' => 'Channel',
            'B' => 'KindID',
            'C' => 'ChildID',
            'D' => 'UserID',
            'E' => 'RoomID',
            'F' => 'lScore',
            'G' => 'Difen',
            'H' => 'zScore',
            'I' => 'CreateTime',
        ];
        $this->orderField = array_key_exists($this->orderField, $orderMap) ? $this->orderField : 'C';
        $order[$orderMap[$this->orderField]] = $this->orderDirection;

        ////////////////////////////////////////////////////////////////////////////
        $list = table('CYRecordDB.dbo.RecordGameDataChildUserRecord a', 'rydb.record')->field([
            'a.*', 'b.Accounts','c.KindID',
            'b.AccountsType', 'b.Compellation', 'b.GameID', 'b.GameLogonCount', 'b.LastLogonDate',
            'b.LastLogonIP', 'b.NickName', 'b.PassPortID', 'b.RegisterDate',
            'b.RegisterIP', 'b.RegisterMobile'=>'MobilePhone', 'b.Sex', 'b.AccountImgUrl'=>'HeadImgUrl'
        ])
            ->join('CYBasicDB.dbo.AccountsInfo b',   'b.UserID = a.UserID', 'LEFT')
            ->join('CYRecordDB.dbo.RecordCreateTable c',   'c.RecordID = a.ChildID', 'LEFT')

            ->where($conds)->order($order)->paginate();

        $info = table('CYRecordDB.dbo.RecordGameDataChildUserRecord a', 'rydb.record')->field([
            'SUM(a.lScore)'=>'TotalScore', 'SUM(a.zScore)'=>'TotalRMB',
        ])
            ->join('CYBasicDB.dbo.AccountsInfo b',   'b.UserID = a.UserID', 'LEFT')
            ->where($conds)->find();
        ////////////////////////////////////////////////////////////////////////////
        return $this->fetch('', [
            'time1' => $time1,
            'time2' => $time2,
            'search'=> $search,
            'RoomID'=> $RoomID != 0 ? $RoomID : '',
            'list'  => $list,
            'info'  => $info,
            'Channel'   => $Channel,
            'CHANNELS'  => $CHANNELS,
            'GAME_KIND' => $GAME_KIND,
            'KindID'    => $KindID,
        ]);
    }

  /**
   *  @brie户输赢7日
   *  @return : page
   *  @details: 
   */
  public function day7Action() {
    $conds = [];
    $order = [];
    $CHANNELS = $this->GetAdminChannel();
    $SHOWS = [0 => '全部显示', 1 => '显示分数', 2 => '显示得分'];
    ////////////////////////////////////////////////////////////////////////////
    $show = $this->request->param('show/d', 1);
    $show = array_key_exists($show, $SHOWS) ? $show : 0;
    ////////////////////////////////////////////////////////////////////////////
    $time = $this->request->param('time/s', '', 'trim,YmdHis2Unix');
    $time = YmdHis2Unix(date('Y-m-d 00:00:00', $time > 0 ? $time : time()));
    $TMS = [
      [$time - 0 * 24 * 60 * 60, $time + 1 * 24 * 60 * 60], // day0
      [$time - 1 * 24 * 60 * 60, $time - 0 * 24 * 60 * 60],
      [$time - 2 * 24 * 60 * 60, $time - 1 * 24 * 60 * 60],
      [$time - 3 * 24 * 60 * 60, $time - 2 * 24 * 60 * 60],
      [$time - 4 * 24 * 60 * 60, $time - 3 * 24 * 60 * 60],
      [$time - 5 * 24 * 60 * 60, $time - 4 * 24 * 60 * 60],
      [$time - 6 * 24 * 60 * 60, $time - 5 * 24 * 60 * 60], // day6
      [$time - 6 * 24 * 60 * 60, $time + 1 * 24 * 60 * 60], // day7 合计
    ];
    $arr = [];
    foreach($TMS as $k => $v) {
      if ($show == 0 || $show == 1) {
        $key = sprintf("( SELECT ISNULL(SUM (e.lScore), 0) FROM CYRecordDB.dbo.RecordGameDataChildUserRecord e WHERE e.UserID = c.UserID AND e.CreateTime BETWEEN '%s' AND '%s' )", YmdHis($v[0]), YmdHis($v[1]));
        $arr[$key] = "day{$k}";
      }
      if ($show == 0 || $show == 2) {
        $key = sprintf("( SELECT ISNULL(SUM (e.zScore), 0) FROM CYRecordDB.dbo.RecordGameDataChildUserRecord e WHERE e.UserID = c.UserID AND e.CreateTime BETWEEN '%s' AND '%s' )", YmdHis($v[0]), YmdHis($v[1]));
        $arr[$key] = "day_{$k}";
      }
    }
    ////////////////////////////////////////////////////////////////////////////
    $search = $search = $this->request->param('search/s', '', 'trim');
    if (!empty($search)) {
      if (is_numeric($search) && $search > 0 && $search < PHP_INT_MAX) {
        $conds['b.UserID|b.GameID'] = $search;
      } else {
        $conds['b.NickName'] = ['LIKE', "%{$search}%"];
      }
    }
    ////////////////////////////////////////////////////////////////////////////
    $yqcode = $this->request->param('yqcode/d', 0);
    if ($yqcode > 0) {
      $conds['g.GameID'] = $yqcode;
    }
    ////////////////////////////////////////////////////////////////////////////
    $channel = $this->request->param('channel/d', 0);
    if ($channel > 0 && array_key_exists($channel, $CHANNELS)) {
      $conds['b.Channel'][] = ['IN', array_keys($CHANNELS)];
      $conds['b.Channel'][] = ['EQ', $channel];
    } else {
      $conds['b.Channel'] = ['IN', array_keys($CHANNELS)];
    }
    ////////////////////////////////////////////////////////////////////////////
    $orderMap = [
      'A' => 'Channel',
      'B' => 'GameID',
      'C' => 'AGameID',
      'D' => $show == 2 ? 'day_6' : 'day6',
      'E' => $show == 2 ? 'day_5' : 'day5',
      'F' => $show == 2 ? 'day_4' : 'day4',
      'G' => $show == 2 ? 'day_3' : 'day3',
      'H' => $show == 2 ? 'day_2' : 'day2',
      'I' => $show == 2 ? 'day_1' : 'day1',
      'J' => $show == 2 ? 'day_0' : 'day0',
      'K' => $show == 2 ? 'day_7' : 'day7',
      'L' => $show == 2 ? 'days2' : 'days',
    ];
    $this->orderField = array_key_exists($this->orderField, $orderMap) ? $this->orderField : 'G';
    $order[$orderMap[$this->orderField]] = $this->orderDirection;
    ////////////////////////////////////////////////////////////////////////////
    $sql = table('CYRecordDB.dbo.RecordGameDataChildUserRecord a', 'rydb.record')->field('a.UserID')->group('a.UserID')->buildSql();
    $list = table("{$sql} c", 'rydb.basic')->field(array_merge([
      'b.UserID', 'b.GameID', 'b.NickName', 'b.AccountsType', 'b.Channel', 'b.RegisterDate', 'b.AccountImgUrl',
      'b.SpreaderID' => 'AUserID', 'g.Compellation' => 'ACompellation', 'g.GameID' => 'AGameID', 'h.AccountImgUrl' => 'AHeadImgUrl',
      '( SELECT ISNULL(SUM (e.lScore), 0) FROM CYRecordDB.dbo.RecordGameDataChildUserRecord e WHERE e.UserID = c.UserID )' => 'days',
      '( SELECT ISNULL(SUM (e.zScore), 0) FROM CYRecordDB.dbo.RecordGameDataChildUserRecord e WHERE e.UserID = c.UserID )' => 'days2',
    ], $arr))
    ->join('CYBasicDB.dbo.AccountsInfo b', 'c.UserID = b.UserID', 'LEFT')
    ->join('CYWebSMSDB.dbo.AgentReg g', 'g.UserID > 0 AND g.UserID = b.SpreaderID', 'LEFT')
    ->join('CYBasicDB.dbo.AccountsInfo h', 'h.UserID = g.UserID', 'LEFT')
    ->where($conds)->order($order);
    ///
    $fmcode = $this->request->param('fmcode/d', 0);
    if ($fmcode > 0) {
      $list = $list->whereExp('b.UserID', " IN(SELECT [c].[MemberUID] FROM [CYBasicDB].dbo.AccountsInfo [a] LEFT JOIN [CYWebSMSDB].dbo.Family [b] ON [b].[AUID] = [a].[UserID] LEFT JOIN [CYWebSMSDB].dbo.FamilyMember [c] ON [c].[FamilyID] = b.ID AND c.Status = 1 WHERE [a].[GameID] = {$fmcode})");
    }
    $list = $list->paginate();
    ////////////////////////////////////////////////////////////////////////////
    return $this->fetch('', [
      'CHANNELS'  => $CHANNELS,
      'SHOWS'     => $SHOWS,
      'show'    => $show,
      'channel' => $channel,
      'URL_GAME_INDEX'  => url('index'),
      'list'  => $list,
      'time'  => $time,
      'search'=> $search,
      'yqcode'=> $yqcode == 0 ? '' : $yqcode,
      'fmcode'=> $fmcode == 0 ? '' : $fmcode,
    ]);
  }
  /**
   *  @brief  : 用户管理-房间数据
   *  @return : page
   *  @details: 
   */
  public function recordAction() {
    $conds = [];
    $order = ['InsertTime'=>'DESC'];
    ////////////////////////////////////////////////////////////////////////////
    $search = $this->request->param('search/s', '', 'trim');
    if (!empty($search)) {
      if ($search > 0) {
        $conds['a.RecordID|a.RoomID'] = $search;
      }
    }
    
    $time1 = $this->request->param('time1/s', '', 'trim');
    $time2 = $this->request->param('time2/s', '', 'trim');
    
    $aa = YmdHis2Unix($time1);
    $bb = YmdHis2Unix($time2);
    $ta = date('Y-m-d 00:00:00', $aa);
    $tb = date('Y-m-d 23:59:59', $bb);
    if ($aa > 0) {
      if ($bb > 0) {
        if ($aa <= $bb) {
          $conds['a.InsertTime'] = ['BETWEEN TIME', [$ta, $tb]];
        } else {
          $conds['a.InsertTime'] = ['>= TIME', $ta];
        }
      } else {
        $conds['a.InsertTime'] = ['>= TIME', $ta];
      }
    } else {
      if ($bb > 0) {
        $conds['a.InsertTime'] = ['<= TIME', $tb];
      }
    }
    
    ////////////////////////////////////////////////////////////////////////////
    $list = table('CYRecordDB.dbo.RoomNumberAllRecord a', 'rydb.record')->field([
      'a.RecordID', 'a.RoomID', 'a.InsertTime',
    ])->where($conds)->order($order)->paginate();
    ////////////////////////////////////////////////////////////////////////////
    return $this->fetch('', [
      'search'=> $search,
      'time1' => $time1,
      'time2' => $time2,
      'list'  => $list,
    ]);
  }
  /**
   *  @brief  : 用户管理-录像回放
   *  @return : page
   *  @details: 数据量大, 前端直接跳转
   */
  public function replayAction() {
    return $this->fetch('', ['list' => []]);
  }
  /**
   *  @brief  : 用户管理-游戏详情
   *  @return : page
   *  @details: 
   */
  public function detailAction() {
      $UserData = [];
      $RecordID = $this->request->param('RecordID/d', 0);
      $RoomCardID = $this->request->param('RoomID/d', 0);
      do {
          if ($RecordID <= 0) {
              if ($RoomCardID <= 0){
                  break;
              }
              $RecordID = table('CYRecordDB.dbo.RecordCreateTable', 'rydb.record')->where('RoomCardID', $RoomCardID)->value("RecordID");
          }

      $eax = table('CYRecordDB.dbo.RecordCreateTable', 'rydb.record')->where('RecordID', $RecordID)->find();
      if (empty($eax)) {
        break;
      }

      $UserDatas = json_decode($eax['TableInfo'],true);

      $UserData['KindID'] = $eax['KindID'];
      $UserData['RoomNum'] = $eax['RoomCardID'];
      $UserData['ServerID'] = $eax['ServerID'];
      $UserData['RecordID'] = $eax['RecordID'];
      $UserData['CreateTime'] = $eax['CreateTime'];
      $UserData['GroupID'] = $eax['RecordGroupID'];
      $UserData['PayMode'] = $UserDatas['paymode']; // 支付方式
      $UserData['TableOwnerID'] = $eax['UserID'];   // 房主
      $UserData['PlayTime'] = $eax['CreateTime'];   //
      $UserData['MaxUserCount'] = $UserDatas['maxgameplayercount']; //开局人数
      $UserData['MaxPlayGameCount'] = $UserDatas['maxgamecount'];   //开局局数
      $UserData['Rule'] = $UserDatas['gamerule'];   //创建规则

      $users = table('CYRecordDB.dbo.RecordGameDataChildUserRecord a', 'rydb.record')
          ->field(['b.UserID','b.GameID','b.NickName','b.AccountImgUrl','a.TableNum','SUM(a.zScore)'=>'zScore'])
          ->join('CYBasicDB.dbo.AccountsInfo b','b.UserID = a.UserID','LEFT')
          ->where('ChildID',$RecordID)->group('b.UserID,b.GameID,b.AccountImgUrl,a.TableNum,b.NickName')->buildSql();
      //去除buildSql多余语句
      $users2 = sql_pure($users);
      //筛选用到的字段结果集
      $users = table("{$users2} c", 'rydb.record')->column('c.UserID,c.GameID,c.AccountImgUrl,c.TableNum,c.NickName,c.zScore');
      foreach ($users as $k => $v){
          $us[$v['TableNum']] = $v;
      }
        //创建新的数据数组
        for ($i=0;$i<$UserData['MaxUserCount'];$i++){
            $UserData['Score'][$i] = 999999999;
            $UserData['UserID'][$i] = 0;
            $UserData['GameID'][$i] = 0;
            $UserData['NickName'][$i] = '';
            $UserData['WxHead'][$i] = '';
        }
        //将比对后的数据赋值到创建的新数组
        for ($i=0;$i<$UserData['MaxUserCount'];$i++){
            foreach ($us as $k => $v) {
                if ($UserData['Score'][$k] == $v['TableNum']) {
                    $UserData['Score'][$k] = 999999999;
                    $UserData['UserID'][$k] = 0;
                    $UserData['GameID'][$k] = 0;
                    $UserData['NickName'][$k] = '';
                    $UserData['WxHead'][$k] = '';
                }else{
                    $UserData['Score'][$k] = $v['zScore'];
                    $UserData['UserID'][$k] = $v['UserID'];
                    $UserData['GameID'][$k] = $v['GameID'];
                    $UserData['NickName'][$k] = $v['NickName'];
                    $UserData['WxHead'][$k] = $v['AccountImgUrl'];
                }
            }
        }
        //查询小局战绩
      $eax = table('CYRecordDB.dbo.RecordGameDataChild', 'rydb.record')->where('dwRecordID',$RecordID)->select();

      if (empty($eax)) {
        break;
      }
      //开始时间结束时间合并到child数组
      $eax2 = array_column($eax,'UserData');
      for ($i=0;$i<count($eax2);$i++) {
            $UserData['RecordChild'][$i]['StartTime'] = $eax[$i]['StartTime'];
            $UserData['RecordChild'][$i]['EndTime'] = $eax[$i]['EndTime'];
            $UserData['RecordChild'][$i]['UserData'] = json_decode($eax2[$i],true);
      }
    } while (false);
    //分割json数据中的牌型
    $a = count($UserData['RecordChild']);
    for ($j=0;$j<$a;$j++){
        $b = count($UserData['RecordChild'][$j]['UserData']['UserInfo']);
        for ($k=0;$k<$b;$k++){
            $UserData['RecordChild'][$j]['UserData']['UserInfo'][$k]['card'] = explode(',',$UserData['RecordChild'][$j]['UserData']['UserInfo'][$k]['card']);
        }
    }
    //json数据中的牌、底分、是否托管、根据chairid椅子号重新分组
    for ($r=0;$r<$a;$r++){
        for ($l=0;$l<$UserData['MaxUserCount'];$l++){
            $UserData['RecordChild'][$r]['Score'][$l] = 999999999;
            $UserData['RecordChild'][$r]['card'][$l] = '';
            $UserData['RecordChild'][$r]['trustee'][$l] = 999999999;
        }
      }
    for ($c=0;$c<$a;$c++){
        $b = count($UserData['RecordChild'][$c]['UserData']['UserInfo']);
        for ($q=0;$q<$b;$q++) {
            $aa = $UserData['RecordChild'][$c]['UserData']['UserInfo'][$q]['chairid'];
            $UserData['RecordChild'][$c]['card'][$aa] = $UserData['RecordChild'][$c]['UserData']['UserInfo'][$q]['card'];
            $UserData['RecordChild'][$c]['Score'][$aa] = $UserData['RecordChild'][$c]['UserData']['UserInfo'][$q]['endScore'];
            $UserData['RecordChild'][$c]['trustee'][$aa] = $UserData['RecordChild'][$c]['UserData']['UserInfo'][$q]['trustee'];
        }
    }

    $KindID = 0;
    if (!empty($UserData)) {
      $KindID = $UserData['KindID'];
      $eax = $UserData['TableOwnerID'] ?? [];
      if (!empty($eax)) {
        $Agent = table('CYBasicDB.dbo.AccountsGameCurrency a', 'rydb.basic')->field([
          'a.UserID',
          'b.SpreaderID' => 'AUserID',
          'ISNULL(b.GameID, 0)' => 'AGameID',
          "ISNULL(b.Compellation, '')" => 'ACompellation',
        ])
        ->join('CYBasicDB.dbo.AccountsInfo b', 'b.UserID = a.UserID', 'LEFT')
        ->join('CYBasicDB.dbo.AccountsInfo c', 'c.UserID = b.SpreaderID', 'LEFT')
        ->join('CYBasicDB.dbo.ChannelConfig w', 'w.ID = c.Channel', 'LEFT')
        ->whereIn('a.UserID', $eax)

        ->select();
      }
    }
    ////////////////////////////////////////////////////////////////////////////
    if (empty($RecordID) || empty($UserData)) {
      return $this->error("Oh~暂无数据!{$RecordID}");
    }
    // 50=十三张; 52=八张; 20=房卡牛牛; 30=嵊州牛牛; 31=欢乐牛牛; 32=开心牛牛;
    if (!in_array($KindID, [143,50, 52, 20, 30, 31, 32])) {
      return $this->error("Oh~暂未处理KindID={$KindID}");
    }
    // echo "<pre/>";
    // print_r($UserData);die;
    return $this->fetch('', [
      'RecordID'  => $RecordID,
      'u'         => $UserData ?? [],
      'Agent'     => $Agent ?? [],
      'GAME_KIND' => GetGameKind(),
    ]);
  }
  /**
   *  @brief  : 拆解二进制`PrivateRandTotalRecord`结构
   *  @param [in] $arr : 二进制字符串数组
   *  @return : array/Exception
   *  @details: 
   */
  protected static function unpack($arr) {
    $pkg = [];
    if (count($arr) > 0) {
      $pkg = self::unpack_head($arr[0]);
      //var_dump($pkg);die;
      for ($i = 1; $i < count($arr); $i++) {
        $pkg['RecordChild'][] = self::unpack_body($arr[$i], $pkg['KindID']);
      }
    }
    return $pkg;
  }
  // PrivateRandTotalRecord
  protected static function unpack_head($data) {

    // 结构特殊处理
    $GroupID = unpack('VGroupID', $data)['GroupID'];
    if ($GroupID == 0 || strlen($GroupID) == 6) { // 侦测是否为六位群号, 群号可能为0
      $retn = unpack('VGroupID/VKindID/VServerID/VRoomNum/VMaxUserCount/CMaxPlayGameCount/VTableOwnerID/CPayMode', $data);
      $buf = substr($data, 4 * 6 + 1 * 2);
    } else {
      $retn = unpack('VKindID/VServerID/VRoomNum/VMaxUserCount/CMaxPlayGameCount/VTableOwnerID/CPayMode', $data);
      $buf = substr($data, 4 * 5 + 1 * 2);
    }

    // std::vector<int>  lScoreVt;
    $len = unpack('Vlen', $buf)['len'];
    $eax = unpack("Vlen/l{$len}", $buf);
    $buf = substr($buf, 4 + 4 * $len);
    unset($eax['len']);
    $retn['Score'] = array_slice($eax, 0);

    // std::vector<int>  dwUserIDVt;
    $len = unpack('Vlen', $buf)['len'];
    $eax = unpack("Vlen/V{$len}", $buf);
    $buf = substr($buf, 4 + 4 * $len);
    unset($eax['len']);
    $retn['UserID'] = array_slice($eax, 0);

    // std::vector<int>  dwGameIDVt;
    $len = unpack('Vlen', $buf)['len'];
    $eax = unpack("Vlen/V{$len}", $buf);
    $buf = substr($buf, 4 + 4 * $len);
    unset($eax['len']);
    $retn['GameID'] = array_slice($eax, 0);

    // std::vector<std::vector<DWORD>> szNickNameVt;
    $size = unpack('Vsize', $buf)['size'];
    $buf = substr($buf, 4 * 1);
    for ($i = 0; $i < $size; $i++) {
      $len = unpack('Vlen', $buf)['len'];
      $eax = unpack('Vlen/a'.($len * 4).'buf', $buf);
      // 'CP12000'/'UCS-4LE'/'UCS4LE'|'UTF-32LE'/'UTF32LE'|'UCS-4-INTERNAL',
      $retn['NickName'][] = iconv('UCS-4LE', 'UTF-8', $eax['buf']);
      $buf = substr($buf, 4 * 1 + $len * 4);
    }

    // std::vector<std::vector<DWORD>> szWxHeadVt;
    $size = unpack('Vsize', $buf)['size'];
    $buf = substr($buf, 4 * 1);
    for ($i = 0; $i < $size; $i++) {
      $len = unpack('Vlen', $buf)['len'];
      $eax = unpack('Vlen/a'.($len * 4).'buf', $buf);
      // 'CP12000'/'UCS-4LE'/'UCS4LE'|'UTF-32LE'/'UTF32LE'|'UCS-4-INTERNAL',
      $retn['WxHead'][] = iconv('UCS-4LE', 'UTF-8', $eax['buf']);
      $buf = substr($buf, 4 * 1 + $len * 4);
    }

    // std::vector<unsigned char>  bRule;
    $len = unpack('Vlen', $buf)['len'];
    $eax = unpack("Vlen/C{$len}", $buf);
    $buf = substr($buf, 4 + $len);
    unset($eax['len']);
    $retn['Rule'] = array_slice($eax, 0);

    // SYSTEMTIME  kPlayTime;
    $eax = unpack('vYear/vMonth/vDayOfWeek/vDay/vHour/vMinute/vSecond/vMilliseconds', $buf);
    $eax = mktime($eax['Hour'], $eax['Minute'], $eax['Second'], $eax['Month'], $eax['Day'], $eax['Year']);
    $retn['PlayTime'] = date('Y-m-d H:i:s', $eax);
    $buf = substr($buf, 2 * 8);

    return $retn;
  }
  // RecordChild
  protected static function unpack_body($data, $KindID = 0) {
    $elm = [];
    $len = unpack('Vlen', $data)['len'];
    $eax = unpack("Vlen/l{$len}", $data);

    $buf = substr($data, 4 + 4 * $len);

    unset($eax['len']);

    $elm['Score'] = array_slice($eax, 0);

    $eax = unpack('vYear/vMonth/vDayOfWeek/vDay/vHour/vMinute/vSecond/vMilliseconds', $buf);
    $eax = mktime($eax['Hour'], $eax['Minute'], $eax['Second'], $eax['Month'], $eax['Day'], $eax['Year']);
    $elm['StartTime'] = date('Y-m-d H:i:s', $eax);
    $buf = substr($buf, 2 * 8);
    
    $eax = unpack('vYear/vMonth/vDayOfWeek/vDay/vHour/vMinute/vSecond/vMilliseconds', $buf);
    $eax = mktime($eax['Hour'], $eax['Minute'], $eax['Second'], $eax['Month'], $eax['Day'], $eax['Year']);
    $elm['EndTime'] = date('Y-m-d H:i:s', $eax);
    $buf = substr($buf, 2 * 8);

    $eax = unpack('lRecordID/Vsize', $buf);
    $elm['RecordID'] = $eax['RecordID'];
    $size = $eax['size']; // 几个GameData, 好像总为1
    $buf = substr($buf, 4 * 2);

    $elm['GameData'] = [];
    for ($j = 0; $j < $size; $j++) {
      $len = unpack('vChairID/vSubCmdID/vDataSize/Vlen', $buf)['len'];
      $GameData = unpack("vChairID/vSubCmdID/vDataSize/Vlen/a{$len}RecordGame", $buf);
      $buf = substr($buf, 2 * 3 + 4 + $len);
      unset($GameData['len']);
      $tmp = $GameData['RecordGame'];
      if ($KindID == 50 || $KindID == 52) { // 十三张|八张
        $RecordGame = [];
        // std::vector<int>  lEndScore;  //下注得分
        $len = unpack('Vlen', $tmp)['len'];

        $eax = unpack("Vlen/l{$len}", $tmp);
        $tmp = substr($tmp, 4 + 4 * $len);
        unset($eax['len']);
        $RecordGame['EndScore'] = array_slice($eax, 0);
       // std::vector<std::vector<BYTE>>  cbCardData; //玩家的扑克数据
        $CardData = [];
        $ecx = unpack('Vecx', $tmp)['ecx'];

        $tmp = substr($tmp, 4);

        for ($k = 0; $k < $ecx; $k++) {
          $len = unpack('Vlen', $tmp)['len'];
          $eax = unpack("Vlen/C{$len}", $tmp);
          $tmp = substr($tmp, 4 + $len);
          unset($eax['len']);
          $CardData[] = array_slice($eax, 0);
        }

        $RecordGame['CardData'] = $CardData;

        $GameData['RecordGame'] = $RecordGame;
        //    var_dump($GameData);die;
      } else if (in_array($KindID, [20, 30, 31, 32])) { // 20=房卡牛牛; 30嵊州牛牛; 31=欢乐牛牛; 32=开心牛牛;
        $RecordGame = [];
        // DWORD dwBankerUser;  //庄家用户ID
        $len = unpack('VBankerUser/Vlen', $tmp)['len'];
        $eax = unpack("VBankerUser/Vlen/C{$len}", $tmp);
        $tmp = substr($tmp, 4 + 4 + $len);
        $RecordGame['BankerUser'] = $eax['BankerUser'];
        unset($eax['BankerUser'], $eax['len']);
        // std::vector<BYTE> cbCallBanker; //每个玩家叫庄的分数
        $RecordGame['CallBanker'] = array_slice($eax, 0);

        // std::vector<BYTE> cbOxValue;  //每个玩家的牛牛数值（该值-1 然后/20 取整，大于242为特殊牛，参考特殊牛值）
        $len = unpack('Vlen', $tmp)['len'];
        $eax = unpack("Vlen/C{$len}", $tmp);
        $tmp = substr($tmp, 4 + $len);
        unset($eax['len']);
        $RecordGame['OxValue'] = array_slice($eax, 0);
        
        // std::vector<int>  lAddScore ; //下注分数情况
        $len = unpack('Vlen', $tmp)['len'];
        $eax = unpack("Vlen/l{$len}", $tmp);
        $tmp = substr($tmp, 4 + 4 * $len);
        unset($eax['len']);
        $RecordGame['AddScore'] = array_slice($eax, 0);
        
        // std::vector<std::vector<BYTE>>  cbCardData; //玩家的扑克数据
        $CardData = [];
        $ecx = unpack('Vecx', $tmp)['ecx'];
        $tmp = substr($tmp, 4);
        for ($k = 0; $k < $ecx; $k++) {
          $len = unpack('Vlen', $tmp)['len'];
          $eax = unpack("Vlen/C{$len}", $tmp);
          $tmp = substr($tmp, 4 + $len);
          unset($eax['len']);
          $CardData[] = array_slice($eax, 0);
        }
        $RecordGame['CardData'] = $CardData;
        $GameData['RecordGame'] = $RecordGame;
      }
      $elm['GameData'][] = $GameData;
    }
    return $elm;
  }
  /**
   *  @brief  : 举报查询
   *  @return : page
   *  @details:
   */
  public function reportAction(){
    $conds = [];
    $order = [];
    $CHANNELS = $this->GetAdminChannel();
    ////////////////////////////////////////////////////////////////////////////
    $channel = $this->request->param('channel/d', 0);
    $isTodo = $this->request->param('isTodo/d', -1);
    $ISTODOS = $this->isTodo;
    if ($channel > 0 && array_key_exists($channel, $CHANNELS)) {
      $conds['b.Channel'][] = ['IN', array_keys($CHANNELS)];
      $conds['b.Channel'][] = ['EQ', $channel];
    } else {
      $conds['b.Channel'] = ['IN', array_keys($CHANNELS)];
    }
      if ($isTodo >= 0 && array_key_exists($isTodo, $ISTODOS)) {
          $conds['isTodo'][] = ['IN', array_keys($ISTODOS)];
          $conds['isTodo'][] = ['EQ', $isTodo];
      } else {
          $conds['isTodo'] = ['IN', array_keys($ISTODOS)];
      }
    ////////////////////////////////////////////////////////////////////////////
    $search1 = $this->request->param('search1/s', '', 'trim');
    if (!empty($search1)) {
      if ($search1 > 0) {
        $conds['a.UserID|b.GameID'] = $search1;
      } else {
        $conds['b.NickName'] = ['LIKE', "%{$search1}%"];
      }
    }
    $search2 = $this->request->param('search2/s', '', 'trim');
    if (!empty($search2)) {
      if ($search2 > 0) {
        $conds['d.UserID|a.GameID'] = $search2;
      } else {
        $conds['d.NickName'] = ['LIKE', "%{$search2}%"];
      }
    }
    ////////////////////////////////////////////////////////////////////////////
    $orderMap = [
      'B' => 'Channel',
      'C' => 'GameID',
      'D' => 'GameID2',
      'E' => 'CreateTime',
      'F' => 'szMessage',
    ];
    $this->orderField = array_key_exists($this->orderField, $orderMap) ? $this->orderField : 'E';
    $order[$orderMap[$this->orderField]] = $this->orderDirection;
    ////////////////////////////////////////////////////////////////////////////
    $list = table('CYRecordDB.dbo.RecordReporMessage a', 'rydb.record')->field([
      'a.ID',
      'a.UserID',
      'b.GameID',
      'b.NickName',
      'a.szMessage',
      'a.isTodo',
      'a.FeedBackMsg',
      'a.CreateTime',
      'b.SpreaderID' => 'SpreaderID1',
      'b.Channel',
      'b.AccountImgUrl' => 'Avatar',
      'd.UserID' => 'UserID2',
      'a.GameID' => 'GameID2',
      'd.NickName' => 'NickName2',
      'd.SpreaderID' => 'SpreaderID2',
      'd.AccountImgUrl' => 'Avatar2',
    ])
    ->join('CYBasicDB.dbo.AccountsInfo b', 'b.UserID = a.UserID', 'LEFT')
    ->join('CYBasicDB.dbo.AccountsInfo d', 'd.GameID = a.GameID', 'LEFT')
    ->where($conds)->order($order)->paginate();
    ////////////////////////////////////////////////////////////////////////////
    return $this->fetch('', [
      'CHANNELS'=> $CHANNELS,
      'isTodo'  => $this->isTodo,
      'isto'    => $isTodo,
      'channel' => $channel,
      'search1' => $search1,
      'search2' => $search2,
      'KindID'  => 0,
      'list'    => $list,
    ]);
  }

    /**
     *  @brief  : 举报详情处理
     *  @return : data
     *  @details:
     */
  public function repordetailAction(){
      $MsgID = $this->request->param('id/d',0);
      $UserID = $this->request->param('UserID/d',0);
      $cond=[];
      $cond['a.UserID']=$UserID;
      $cond['a.ID'] = $MsgID;
      if($this->request->isGet()){
          $isTodo = $this->isTodo;
          $row = table('RecordReporMessage a','rydb.record')->field([
              'a.*','b.NickName','c.NickName'=>'GNickName'
          ])
              ->join('CYBasicDB.dbo.AccountsInfo B','B.UserID=a.UserID','LEFT')
              ->join('CYBasicDB.dbo.AccountsInfo c','c.GameID=a.GameID','LEFT')
              ->where($cond)->find();
          return  $this->fetch('',[
              'row'=>$row,
              'isTodo'=>$isTodo
          ]);
      }else if($this->request->isPost()){
          $data = [
              'szMessage'   => $this->request->param('szMessage/s', '', 'trim'),
              'FeedBackMsg' => $this->request->param('FeedBackMsg/s', '', 'trim'),
              'isTodo'    => $this->request->param('isTodo/d', 0),

          ];
          $data['UpdateTime'] = new Expression('GETDATE()');
          //--- 验证器验证 ---
          $retn = $this->validate($data, [ // 按照顺序逐一判断
              'szMessage|举报内容'   => 'require|max:128',
              'FeedBackMsg|客服回复处理结果信息' => 'require|max:255',
              'isTodo|处理结果'    => 'require|integer|in:0,1,2',

          ]);
          if (true !== $retn) {
              return result([], 100, $retn);
          }
          table('CYRecordDB.dbo.RecordReporMessage','rydb.record')->where($cond)->update($data);
          return result([],0);

      }

  }
}
